import { CreateMeta, HoleMeta } from '@/model/meta/MetaClass';
import { Matrix3, Vector3 } from 'three';

import AluGeoUtil from "./utils/AluGeoUtil";
import AModelFmulaUtils from '../utils/AModelFmulaUtils';

export default class LineMouthGeo {

    private _vertices: Array<number>;
    get vertices() { return this._vertices; }

    private _indices: Array<number>;
    get indices() { return this._indices; }


    private _holeR: Array<Array<number>>;


    constructor(data: AIBasicParams) {
        this._vertices = [];
        this._indices = [];

        this.generate(data);
    }

    private generate(data: AIBasicParams) {

        let hw = +data.dkW;
        let hl = +data.dkL;

        let hw2 = hw / 2;
        let hl2 = hl / 2;

        let l = +data.L;
        let w = +data.W;

        let l2 = l / 2;
        let w2 = w / 2;

        this._holeR = [
            [w2 - hw2, l2 - hl2],
            [w2 + hw2, l2 - hl2],
            [w2 + hw2, l2 + hl2],
            [w2 - hw2, l2 + hl2]
        ]


        this._top(data);

        this._hole(data);

        this._side(data);

        this._rid(data);


        //x正旋90
        let ar = -0.5 * Math.PI;

        let q = new Matrix3();
        q.set(
            1, 0, 0,
            0, Math.cos(ar), Math.sin(ar),
            0, -Math.sin(ar), Math.cos(ar)
        );

        let v = new Vector3(1, 0, 0);

        for (let i: number = 0; i < this._vertices.length; i += 3) {
            v.set(this._vertices[i], this._vertices[i + 1], this._vertices[i + 2]).applyMatrix3(q);

            this._vertices[i] = v.x;
            this._vertices[i + 1] = v.y;
            this._vertices[i + 2] = v.z;
        }
    }

    /** 封板*/
    private _top(data: AIBasicParams) {
        // let l = +data.H, sl = 50, sw = 50, w = +data.BKH, t = +data.bkT;

        let l = +data.L, w = +data.W, t = +data.GMT;

        let back = [
            0, 0, 0, w, 0, 0, w, l, 0, 0, l, 0
        ];

        let front = [
            0, 0, t, w, 0, t, w, l, t, 0, l, t
        ];

        let bHoles = [];
        let fHoles = [];
        this._holeR.map((c) => {
            bHoles.push(...c, 0);
            fHoles.push(...c, t);
            return v;
        })


        // [hw, 0, -t, hw + 50, 0, -t, hw + 50, hl, -t, hw, hl, -t];
        //  = [hw, 0, 0, hw + 50, 0, 0, hw + 50, hl, 0, hw, hl, 0];

        let h = new HoleMeta(null, null, null, null, null, [[bHoles, fHoles]])
        let c = new CreateMeta(t, front, back, h);
        let r = AluGeoUtil.createBoardWithHole(c);

        let ar = 0.5 * Math.PI;

        let q = new Matrix3();
        q.set(
            1, 0, 0,
            0, Math.cos(ar), Math.sin(ar),
            0, -Math.sin(ar), Math.cos(ar)
        );

        let v = new Vector3(1, 0, 0);
        v.applyMatrix3(q);

        console.log(v);




        let len = this._vertices.length / 3;
        this._indices.push(...r.indices.map((v) => { return v + len }));
        this._vertices.push(...r.vertices);
    }

    /** 洞口*/
    private _hole(data: AIBasicParams) {

        let hMin = this._holeR[0];
        let hMax = this._holeR[2];


        //洞的四个边
        //底 平行横肋
        this._hole_side_lf(data, hMin[0] - +data.ZYKH, hMin[1]);
        this._hole_side_lf(data, hMax[0], hMin[1]);


        this._hole_side_bt(data, hMin[1]);
        this._hole_side_bt(data, hMax[1] + +data.SXKH);

        this._hole_hRid(data);
    }

    private _hole_side_lf(data: AIBasicParams, x: number, y: number) {
        let l = +data.dkL, w = +data.ZKH - +data.GMT, t = +data.ZYKH;

        let back = [
            0, 0, -t, w, 0, -t, w, l, -t, 0, l, -t
        ];

        let front = [
            0, 0, 0, w, 0, 0, w, l, 0, 0, l, 0
        ];

        let ar = Math.PI * -0.5;
        let m = new Matrix3();
        let v = new Vector3();
        m.set(
            Math.cos(ar), 0, Math.sin(ar),
            0, 1, 0,
            -1 * Math.sin(ar), 0, Math.cos(ar)
        )


        let c = new CreateMeta(t, front, back, null);
        let r = AluGeoUtil.createBoardWithHole(c);

        for (let i: number = 0; i < r.vertices.length; i += 3) {
            v.set(r.vertices[i], r.vertices[i + 1], r.vertices[i + 2]).applyMatrix3(m);
            r.vertices[i] = v.x + x;
            r.vertices[i + 1] = v.y + y;
            r.vertices[i + 2] = v.z + +data.GMT;
        }

        let len = this._vertices.length / 3;
        this._indices.push(...r.indices.map((v) => { return v + len }));
        this._vertices.push(...r.vertices);

    }

    private _hole_side_bt(data: AIBasicParams, offY: number) {
        let l = +data.SKH - +data.GMT, w = +data.W - 2 * +data.ZYKH, t = +data.SXKH;

        // let offY = +data.L;

        let back = [
            0, 0, 0, w, 0, 0, w, l, 0, 0, l, 0
        ];

        let front = [
            0, 0, t, w, 0, t, w, l, t, 0, l, t
        ];

        let ar = Math.PI * 0.5;
        let m = new Matrix3();
        let v = new Vector3();
        m.set(
            1, 0, 0,
            0, Math.cos(ar), -Math.sin(ar),
            0, Math.sin(ar), Math.cos(ar)
        )


        let c = new CreateMeta(t, front, back, null);
        let r = AluGeoUtil.createBoardWithHole(c);

        for (let i: number = 0; i < r.vertices.length; i += 3) {
            v.set(r.vertices[i], r.vertices[i + 1], r.vertices[i + 2]).applyMatrix3(m);
            r.vertices[i] = v.x + +data.ZYKH;
            r.vertices[i + 1] = v.y + offY;
            r.vertices[i + 2] = v.z + data.GMT;
        }

        let len = this._vertices.length / 3;
        this._indices.push(...r.indices.map((v) => { return v + len }));
        this._vertices.push(...r.vertices);

    }

    /** 洞口的两条短横肋*/
    private _hole_hRid(data: AIBasicParams) {
        let l = +data.L;
        let w = +data.W;

        let l2 = l / 2;
        let w2 = w / 2;

        let hMin = this._holeR[0];
        let hMax = this._holeR[2];

        let hl = +data.HLW, hw = hMin[0] - +data.ZYKH, ht = +data.HLH;

        let y = l2 - ht / 2;

        this._rid_base(+data.ZYKH, y, hl, hw, ht, +data.GMT);
        this._rid_base(hMax[0], y, hl, hw, ht, +data.GMT);
    }

    /** 洞口板
     * @param x 
     * @param y 
     * @param hl y向
     * @param hw x向
     * @param t 横肋高度
     * @param z 
    */
    private _hole_board(x: number, y: number, hl: number, hw: number, t: number, z = 10) {

    }


    /** 侧板*/
    private _side(data: AIBasicParams) {

        this._side_l(data);

        this._side_r(data);

        this._side_t(data);

        this._side_b(data);
    }

    /** 侧板-左*/
    private _side_l(data: AIBasicParams) {
        let l = +data.L, w = +data.ZKH, t = +data.ZYKH;

        let back = [
            0, 0, -t, w, 0, -t, w, l, -t, 0, l, -t
        ];

        let front = [
            0, 0, 0, w, 0, 0, w, l, 0, 0, l, 0
        ];

        let ar = Math.PI * -0.5;
        let m = new Matrix3();
        let v = new Vector3();
        m.set(
            Math.cos(ar), 0, Math.sin(ar),
            0, 1, 0,
            -1 * Math.sin(ar), 0, Math.cos(ar)
        )

        
        // let holes = AModelFmulaUtils.getHolesbyExpress(data.p_zkkw, w);
        // let filterHole = AluGeoUtil.filterHole(w - (+data.BKDia * 0.5), holes);
        // let holes = AModelFmulaUtils.getHolesbyExpress(data.p_zkkw, l, 2, data, "p_zkkw");
        let h = new HoleMeta(+data.BKDia * 0.5, w - +data.BKKJMDis, data["Ezybkk"]);
    
        let c = new CreateMeta(t, front, back, h);
        let r = AluGeoUtil.createBoardWithHole(c);

        for (let i: number = 0; i < r.vertices.length; i += 3) {
            v.set(r.vertices[i], r.vertices[i + 1], r.vertices[i + 2]).applyMatrix3(m);
            r.vertices[i] = v.x;
            r.vertices[i + 1] = v.y;
            r.vertices[i + 2] = v.z;
        }

        let len = this._vertices.length / 3;
        this._indices.push(...r.indices.map((v) => { return v + len }));
        this._vertices.push(...r.vertices);
    }

    /** 侧板-右*/
    private _side_r(data: AIBasicParams) {
        let l = +data.L, w = +data.YKH, t = +data.ZYKH;
        let offX = +data.W;

        let back = [
            0, 0, 0, w, 0, 0, w, l, 0, 0, l, 0
        ];

        let front = [
            0, 0, t, w, 0, t, w, l, t, 0, l, t
        ];

        let ar = Math.PI * -0.5;
        let m = new Matrix3();
        let v = new Vector3();
        m.set(
            Math.cos(ar), 0, Math.sin(ar),
            0, 1, 0,
            -1 * Math.sin(ar), 0, Math.cos(ar)
        )

        let holes = AModelFmulaUtils.getHolesbyExpress(data.p_ykkw, l, 2, data, "p_ykkw");
        let h = new HoleMeta(+data.BKDia * 0.5, w - +data.BKKJMDis, data["Ezybkk"]);

        let c = new CreateMeta(t, front, back, h);
        let r = AluGeoUtil.createBoardWithHole(c);

        for (let i: number = 0; i < r.vertices.length; i += 3) {
            v.set(r.vertices[i], r.vertices[i + 1], r.vertices[i + 2]).applyMatrix3(m);
            r.vertices[i] = v.x + offX;
            r.vertices[i + 1] = v.y;
            r.vertices[i + 2] = v.z;
        }

        let len = this._vertices.length / 3;
        this._indices.push(...r.indices.map((v) => { return v + len }));
        this._vertices.push(...r.vertices);
    }

    /** 侧板-上*/
    private _side_t(data: AIBasicParams) {
        // let l = 65, w = 400, t = 10;
        let l = +data.SKH, w = +data.W, t = +data.SXKH;

        let offY = +data.L;

        let back = [
            0, 0, 0, w, 0, 0, w, l, 0, 0, l, 0
        ];

        let front = [
            0, 0, t, w, 0, t, w, l, t, 0, l, t
        ];

        let ar = Math.PI * 0.5;
        let m = new Matrix3();
        let v = new Vector3();
        m.set(
            1, 0, 0,
            0, Math.cos(ar), -Math.sin(ar),
            0, Math.sin(ar), Math.cos(ar)
        )

        let holes = AModelFmulaUtils.getHolesbyExpress(data.p_skkw, w, 2, data, "p_skkw");
        let h = new HoleMeta(+data.BKDia * 0.5, l - +data.BKKJMDis, data["Esxbkk"], "x");

        let c = new CreateMeta(t, front, back, h);
        let r = AluGeoUtil.createBoardWithHole(c);

        for (let i: number = 0; i < r.vertices.length; i += 3) {
            v.set(r.vertices[i], r.vertices[i + 1], r.vertices[i + 2]).applyMatrix3(m);
            r.vertices[i] = v.x;
            r.vertices[i + 1] = v.y + offY;
            r.vertices[i + 2] = v.z;
        }

        let len = this._vertices.length / 3;
        this._indices.push(...r.indices.map((v) => { return v + len }));
        this._vertices.push(...r.vertices);
    }

    /** 侧板-下*/
    private _side_b(data: AIBasicParams) {
        // let l = 65, w = 400, t = 10;
        let l = +data.XKH, w = +data.W, t = +data.SXKH;



        let back = [
            0, 0, -t, w, 0, -t, w, l, -t, 0, l, -t
        ];

        let front = [
            0, 0, 0, w, 0, 0, w, l, 0, 0, l, 0
        ];

        let ar = Math.PI * 0.5;
        let m = new Matrix3();
        let v = new Vector3();
        m.set(
            1, 0, 0,
            0, Math.cos(ar), -Math.sin(ar),
            0, Math.sin(ar), Math.cos(ar)
        )


        let holes = AModelFmulaUtils.getHolesbyExpress(data.p_xkkw, w, 2, data, "p_xkkw");
        let h = new HoleMeta(+data.BKDia * 0.5, l - +data.BKKJMDis, data["Esxbkk"], "x");

        let c = new CreateMeta(t, front, back, h);
        let r = AluGeoUtil.createBoardWithHole(c);

        for (let i: number = 0; i < r.vertices.length; i += 3) {
            v.set(r.vertices[i], r.vertices[i + 1], r.vertices[i + 2]).applyMatrix3(m);
            r.vertices[i] = v.x;
            r.vertices[i + 1] = v.y;
            r.vertices[i + 2] = v.z;
        }

        let len = this._vertices.length / 3;
        this._indices.push(...r.indices.map((v) => { return v + len }));
        this._vertices.push(...r.vertices);
    }

    /** 肋*/
    private _rid(data: AIBasicParams) {

        this._rid_h(data);

        this._rid_v(data);
    }

    /** 横肋 y向坐标排列*/
    private _rid_h(data: AIBasicParams) {

        let h = AModelFmulaUtils.getHolesbyExpress(data.p_hldw, +data.L);
        // let h = [50, 100];
        let hl = +data.HLW, hw = +data.W - 2 * +data.ZYKH, ht = +data.HLH;

        let filterMin = this._holeR[0][1] - +data.SXKH;
        let filterMax = this._holeR[2][1] + +data.SXKH;


        for (let offL of h) {
            if (offL > 0) {
                let end = offL + hl;

                if (end < filterMin || offL > filterMax) {
                    this._rid_base(+data.ZYKH, offL, hl, hw, ht, +data.GMT);
                }
            }
        }
    }


    /** 竖肋 x向*/
    private _rid_v(data: AIBasicParams) {

        let h = AModelFmulaUtils.getHolesbyExpress(data.p_sldw, +data.W);

        let hl = +data.L - 2 * +data.SXKH, hw = +data.SLW, ht = +data.SLH;

        for (let offL of h) {
            if (offL > 0) {
                //截成2段
                let hh = this._holeR[0][1] - +data.SXKH;
                this._rid_base(offL, +data.SXKH, hh, hw, ht, +data.GMT);

                //下半段
                this._rid_base(offL,  this._holeR[2][1], hh, hw, ht, +data.GMT);
            }
        }
    }

    /**
     * 
     * @param x 
     * @param y 
     * @param hl y向
     * @param hw x向
     * @param t 横肋高度
     * @param z 
     */
    private _rid_base(x: number, y: number, hl: number, hw: number, t: number, z = 10) {
        let back = [
            0, 0, 0, hw, 0, 0, hw, hl, 0, 0, hl, 0
        ];

        let front = [
            0, 0, t, hw, 0, t, hw, hl, t, 0, hl, t
        ];

        let c = new CreateMeta(t, front, back, null);
        let r = AluGeoUtil.createBoardWithHole(c);

        for (let i: number = 0; i < r.vertices.length; i += 3) {
            // v.set(r.vertices[i], r.vertices[i + 1], r.vertices[i + 2]).applyMatrix3(m);
            r.vertices[i] += x;
            r.vertices[i + 1] += y;
            r.vertices[i + 2] += z;
        }

        let len = this._vertices.length / 3;
        this._indices.push(...r.indices.map((v) => { return v + len }));
        this._vertices.push(...r.vertices);
    }

}